package com.iot.ic.service;


import com.iot.ic.common.Options;
import com.iot.ic.common.Response;
import com.iot.ic.dao.IllegalResultMapper;
import com.iot.ic.dao.IllegalResultShowMapper;
import com.iot.ic.dao.ScenesResultMapper;
import com.iot.ic.model.Device;
import com.iot.ic.model.IllegalResult;
import com.iot.ic.model.IllegalResultShow;
import com.iot.ic.model.ManualIntervention;
import com.iot.ic.model.MatchPause;
import com.iot.ic.model.MatchScenesInfo;
import com.iot.ic.model.ScenesResult;
import com.iot.ic.model.StadiumResult;
import com.iot.ic.model.TeamInfo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created by xiuge on 2017/2/20.
 */
@Service
public class ScenesResultServiceImpl implements ScenesResultService {


    @Autowired
    private IllegalResultService illegalResultService;

    @Autowired
    private StadiumResultService stadiumResultService;

    @Autowired
    private ManualInterventionService manualInterventionService;

    @Autowired
    private ScenesResultMapper scenesResultMapper;
    
    @Autowired
    private MatchPauseService matchPauseService;
    
    @Autowired
    private TeamService teamService;
    
    @Autowired
    private DeviceService deviceService;
    
    @Autowired
    private MatchScenesService matchScenesService;
    
    @Autowired
    private IllegalResultShowService illegalResultShowService;
    
    @Autowired
	SimpMessagingTemplate simpMessagingTemplate;
    


    @Override
    public int addScenesResult(ScenesResult scenesResult) {
        int result = scenesResultMapper.insert(scenesResult);
        return result;
    }

    @Override
    public int updateScenesResult(ScenesResult scenesResult) {
        int result = scenesResultMapper.updateByPrimaryKeySelective(scenesResult);
        return result;
    }

    @Override
    public ScenesResult getScenesResultByScenesAndStadiumResult(int stadiumScenesId, int stadiumResultId) {
        ScenesResult scenesResult = new ScenesResult();
        scenesResult.setStadiumScenesId(stadiumScenesId);
        scenesResult.setStadiumResultId(stadiumResultId);
        ScenesResult scenesResultData = scenesResultMapper.getScenesResultByStadiumScenesAndStadiumResult(scenesResult);
        return scenesResultData;
    }

    public List<Map<String, Object>> getScenesReslutList(int count, int teamId, String startTime, String endTime) {
        List<Map<String, Object>> scenesResultList = scenesResultMapper.selectScenesResultList(count, teamId, startTime, endTime);
        return scenesResultList;
    }

	@Override
	public Map<String, Object> postScenesResult(ScenesResult scenesResult) {
		long starTime = System.currentTimeMillis();
		//获得场景成绩
		ScenesResult dataScenesResult = scenesResultMapper.getSceneInfoBySceneResultId(scenesResult.getScenesResultId());
		//获取场景得分
		int scenesScore = dataScenesResult.getScenesScore();
		
		//获得场景基本信息
		MatchScenesInfo scenesInfo = matchScenesService.getMatchScenesInfo(dataScenesResult.getScenesId()); 
		//获得车队基本信息
		TeamInfo teaminfo = teamService.getTeam(scenesResult.getTeamId());
		//获得赛场成绩基本信息
		StadiumResult oldstadiumResult = stadiumResultService.getStadiumResult(scenesResult.getStadiumResultId());
		
		Map<String, Object> resultMap = new HashMap<String, Object>();
		int endFlag = 0;
		int resultFlag = 0;
		int deductScore = 0;
		//新增违规行为成绩
		List<IllegalResult> illegalResultList = scenesResult.getIllegalResultList();
		
		List<IllegalResult> dataIllegalResultList = new ArrayList<IllegalResult>();
		List<IllegalResultShow> dataIllegalResultShowList = new ArrayList<IllegalResultShow>();
		
		for (IllegalResult illegalResult : illegalResultList) {
			int illegalCount = illegalResult.getIllegalCount();
			int illegalScore = illegalResult.getIllegalScore();
			illegalResult.setCreateTime(new Date());
			illegalResult.setDelFlag(Options.NotDel.getCode());
			illegalResult.setScenesName(scenesInfo.getScenesName());
			illegalResult.setTeamId(scenesResult.getTeamId());
			illegalResult.setScenesResultId(scenesResult.getScenesResultId());
			illegalResult.setDeductScore(illegalScore*illegalCount);
			dataIllegalResultList.add(illegalResult);
			//resultFlag = illegalResultService.addIllegalResult(illegalResult);
			
			
			//新增展示界面违规信息
			IllegalResultShow illegalResultShow = new IllegalResultShow();
			illegalResultShow.setCreateTime(new Date());
			illegalResultShow.setDeductScore(illegalScore*illegalCount);
			illegalResultShow.setDelFlag(0);
			illegalResultShow.setIllegalCount(illegalCount);
			illegalResultShow.setIllegalName(illegalResult.getIllegalName());
			illegalResultShow.setScenesName(scenesInfo.getScenesName());
			illegalResultShow.setScenesResultId(scenesResult.getScenesResultId());
			illegalResultShow.setTeamId(illegalResult.getTeamId());
			illegalResultShow.setScenesNo(dataScenesResult.getScenesNo());
			illegalResultShow.setScenesType(dataScenesResult.getScenesType());
			dataIllegalResultShowList.add(illegalResultShow);
			//int result = illegalResultShowService.addIllegalResultShow(illegalResultShow);
			
			//websocket推送违规信息
		    if (illegalResultShow.getIllegalCount() > 0) {		    	
		    	illegalResultShow.setTeamName(teaminfo.getTeamName());
			    Response response = new Response();
			    response.setResult(illegalResultShow);
			    simpMessagingTemplate.convertAndSend("/topic/testIllegalResultsocketpush", response);
			    simpMessagingTemplate.convertAndSendToUser(teaminfo.getTeamId().toString(), "/testTeamIllegalResultsocketpush", response);
		    }
			if (illegalResult.getIllegalCount() > 0) {
				deductScore = deductScore + illegalScore*illegalCount;
			}
		}
		resultFlag = illegalResultShowService.insertIllegalResultShowBatch(dataIllegalResultShowList);
		resultFlag = illegalResultService.insertIllegalResultBatch(dataIllegalResultList);
		// 扣除违规行为的扣分
		scenesScore = scenesScore - deductScore;
		
		//扣除人工干预的扣分
		List<ManualIntervention> interventionList = manualInterventionService.listManualInterventionByScenes(scenesResult.getScenesResultId());
		for (ManualIntervention manualIntervention : interventionList) {
			if (manualIntervention.getDeductScore() == 0 ){
				scenesScore = 0;
			} else {
				deductScore = deductScore + manualIntervention.getDeductScore();
				scenesScore = (scenesScore -  manualIntervention.getDeductScore());
			}
		}
		//总分为负的 改为0
		scenesScore = scenesScore > 0? scenesScore : 0;
		
		int oldRoadDeductScore = 0;
		int totalScoroRoad = 0;
		int firstRoadFlag = 0;
		if (scenesInfo.getScenesType() == Options.Road.getCode()){
			 scenesResult.setScenesType(Options.Road.getCode());
			 List<ScenesResult> roadResultList = scenesResultMapper.listRoadResult(scenesResult.getStadiumResultId());
			 if (roadResultList != null && roadResultList.size() == 0) {
				 totalScoroRoad = scenesInfo.getScenesScore();
				 firstRoadFlag = 1;
			 }
			 for (ScenesResult roadResult : roadResultList) {
				 oldRoadDeductScore = oldRoadDeductScore + roadResult.getScenesResult();
			 }
		}
		
		//更改场景比赛成绩
		if (resultFlag > 0) {
			if (scenesInfo.getScenesType() == Options.Road.getCode()){
				scenesResult.setScenesResult(deductScore);
				dataScenesResult.setScenesResult(deductScore);
			} else {
				scenesResult.setScenesResult(scenesScore);
				dataScenesResult.setScenesResult(scenesScore);
			}
			scenesResult.setDelFlag(Options.NotDel.getCode());
			scenesResult.setCreateTime(new Date());
			resultFlag = scenesResultMapper.updateByPrimaryKeySelective(scenesResult);	
			//websocket推送
		    if (resultFlag == 1) {
			    Response response=new Response();
			    dataScenesResult.setTeamId(teaminfo.getTeamId());
			    dataScenesResult.setTeamName(teaminfo.getTeamName());
			    dataScenesResult.setStadiumName(oldstadiumResult.getStadiumName());
			    dataScenesResult.setCreateTime(new Date());
			    response.setResult(dataScenesResult);
			    simpMessagingTemplate.convertAndSend("/topic/testScenesResultsocketpush", response);
			    simpMessagingTemplate.convertAndSendToUser(teaminfo.getTeamId().toString(), "/testTeamScenesResultsocketpush", response);
		    }
		}
		
		//更新赛道总成绩
		if (resultFlag > 0) {
			int oldScore = oldstadiumResult.getTotalScore();
			int oldRoadScore = oldstadiumResult.getRoadScore();
			int oldScenesScore = oldstadiumResult.getScenesScore();
			oldScore = oldScore + totalScoroRoad;
			if (scenesInfo.getScenesType() == Options.Road.getCode()){
				List<ScenesResult> roadResultList = scenesResultMapper.listRoadResult(scenesResult.getStadiumResultId());
				if (firstRoadFlag == 1) {
					oldRoadScore = scenesInfo.getScenesScore();
				}
				if(oldRoadDeductScore >= scenesInfo.getScenesScore()){ 
					oldstadiumResult.setTotalScore(oldScore);
				} else {
					int roadDeductScore = 0;
					if ((oldRoadDeductScore + deductScore) >= scenesInfo.getScenesScore()) {
						 roadDeductScore = scenesInfo.getScenesScore() - oldRoadDeductScore;
					} else {
						 roadDeductScore = deductScore;
					}
					oldstadiumResult.setTotalScore(oldScore - roadDeductScore);
				}
				int newRoadScore = (oldRoadScore - deductScore) > 0 ?(oldRoadScore - deductScore):0;
				oldstadiumResult.setRoadScore(newRoadScore);
			} else {
				int newScenesScore = oldScenesScore + scenesScore;
				int newScore = oldScore + scenesResult.getScenesResult();
				oldstadiumResult.setTotalScore(newScore);
				oldstadiumResult.setScenesScore(newScenesScore);
			}
			if (scenesResult.getIsEnd() == 1) {
				oldstadiumResult.setEndTime(new Date());
				oldstadiumResult.setMatchState(1);
				oldstadiumResult.setCompleteFlag(1);
				MatchPause matchPause = new MatchPause();
				matchPause.setStadiumResultId(scenesResult.getStadiumResultId());
				List<MatchPause> matchPauseList =  matchPauseService.listMatchPause(matchPause);
				int pauseTime = 0;
				for (MatchPause matchPauseData : matchPauseList) {
					long startTime = matchPauseData.getStartTime().getTime();
					long endTime = matchPauseData.getEndTime().getTime();
					int pauseTimeData = (int) (endTime - startTime)/1000;
					pauseTime = pauseTime + pauseTimeData;
				}
				long startTime = oldstadiumResult.getStartTime().getTime();
				long endTime = oldstadiumResult.getEndTime().getTime();
				int matchTime = (int) ((endTime - startTime)/1000);
				matchTime = matchTime - pauseTime;
				int timeScore = (matchTime - 1200)>0?(matchTime - 1200):0;
				timeScore = 300 - timeScore*10/60;
				oldstadiumResult.setMatchTime(matchTime);
				oldstadiumResult.setTimeScore(timeScore);
				oldstadiumResult.setTotalScore(oldstadiumResult.getTotalScore() + timeScore);
				List<StadiumResult> stadiumResultList= stadiumResultService.listStadiumResultByTeam(scenesResult.getTeamId());
				if (stadiumResultList.size() == 2) {
					endFlag = 1;
				}
				
				//更改车对状态
				TeamInfo teamInfo = new TeamInfo();
				teamInfo.setTeamId(scenesResult.getTeamId());
				teamInfo.setTeamState(Options.Finish.getCode());
				teamService.updateTeam(teamInfo);
				
				//websocket推送车队状态
				Map<String,Integer> teamStateMap = new HashMap<String,Integer>();
				teamStateMap.put("teamState", Options.Finish.getCode());
				simpMessagingTemplate.convertAndSendToUser(scenesResult.getTeamId().toString(), "/testTeamStatesocketpush", teamStateMap);
				
				//解除设备绑定
				List<Device> deviceList = deviceService.getDeviceListByTeamId(scenesResult.getTeamId());
				for (Device device : deviceList) {
					deviceService.unBindDeviceWithTeam(device.getDeviceId());
				}
			}
			resultFlag  = stadiumResultService.updateStadiumResult(oldstadiumResult);
			
			if (scenesResult.getIsEnd() == 1) { 
				Response response=new Response();
				List<Map<String,Object>> list=stadiumResultService.getStadiumResultDetailByYear(2017);
				response.setResult(list);
				//总成绩榜数据推送
				simpMessagingTemplate.convertAndSend("/topic/testStadiumResultSocketpush", response);
				if (oldstadiumResult.getStadiumId() == Options.CityStadium.getCode()) {
					List<Map<String,Object>> stadiumDataResultList=stadiumResultService.getStadiumResultDetailByStadiumType(1);
					response.setResult(stadiumDataResultList);
					// 城市赛场成绩推送
					simpMessagingTemplate.convertAndSend("/topic/testStadiumResult1Socketpush", response);
				} else if (oldstadiumResult.getStadiumId() == Options.HighSpeedStadium.getCode()) {
					List<Map<String,Object>> stadiumDataResultList=stadiumResultService.getStadiumResultDetailByStadiumType(2);
					response.setResult(stadiumDataResultList);
					// 高速赛场成绩推送
					simpMessagingTemplate.convertAndSend("/topic/testStadiumResul2Socketpush", response);
				} else if (oldstadiumResult.getStadiumId() == Options.Suburbs.getCode()) {
					List<Map<String,Object>> stadiumDataResultList=stadiumResultService.getStadiumResultDetailByStadiumType(3);
					response.setResult(stadiumDataResultList);
					// 高速赛场成绩推送
					simpMessagingTemplate.convertAndSend("/topic/testStadiumResul3Socketpush", response);
				}
			}
		}
		resultMap.put("isEnd", endFlag);
		resultMap.put("result", resultFlag);
		
		long endTime = System.currentTimeMillis();
		System.out.println("耗时:"+(endTime - starTime));
		
		return resultMap;
	}

    @Override
    public List<ScenesResult> listScenesResultByStadiumAndTeam(ScenesResult scenesResult) {
        List<ScenesResult> dataList = new ArrayList<ScenesResult>();
        List<ScenesResult> scenesResults = scenesResultMapper.selectScenesResultListByStadiumAndTeam(scenesResult);
        for (ScenesResult scenesResult2 : scenesResults) {
            List<IllegalResult> illegalResultList = illegalResultService.listIllegalResultByScenes(scenesResult2.getScenesResultId());
            scenesResult2.setIllegalResultList(illegalResultList);
            List<ManualIntervention> manualInterventionList = manualInterventionService.listManualInterventionByScenes(scenesResult2.getScenesResultId());
            scenesResult2.setManualInterventionList(manualInterventionList);
            dataList.add(scenesResult2);
        }
        return dataList;
    }

    @Override
    public List<ScenesResult> getScenesResultWithIllegalAndManual(int scenesId, int teamId) {
        List<ScenesResult> scenesResultList = scenesResultMapper.getScenesResultByScenesWithIllegalAndManual(scenesId, teamId);
        return scenesResultList;
    }

    @Override
    public ScenesResult getScenesInfoByScenesResultId(int scenesResultId) {
        ScenesResult scenesResult = scenesResultMapper.getSceneInfoBySceneResultId(scenesResultId);
        return scenesResult;
    }

    @Override
    public List<ScenesResult> listScenesResultByStadiumResult(int stadiumResultId) {
        List<ScenesResult> scenesResultList = scenesResultMapper.listScenesResultByStadiumResult(stadiumResultId);
        return scenesResultList;
    }

    @Override
    public int updateScenceScore(int scenesResultId) {
        ScenesResult scenesResult = scenesResultMapper.getScenesResultByIdWithIllegalAndManu(scenesResultId);      
        MatchScenesInfo scenesInfo = matchScenesService.getMatchScenesInfo(scenesResult.getScenesId()); 
        
        int totalScoroRoad = 0;
  		if (scenesInfo.getScenesType() == Options.Road.getCode()){
  			 List<ScenesResult> roadResultList = scenesResultMapper.listRoadResult(scenesResult.getStadiumResultId());
  			 for (ScenesResult roadResult : roadResultList) {
  				 totalScoroRoad = totalScoroRoad + roadResult.getScenesResult();
  			 }
  		}
        
        List<IllegalResult> illegalResults = scenesResult.getIllegalResultList();
        int illegalScore = 0;
        if (illegalResults != null && illegalResults.size() != 0) {
            for (IllegalResult illegalResult :
                    illegalResults) {
                if (illegalResult.getIllegalCount() != null && illegalResult.getIllegalScore() != null)
                    illegalScore += illegalResult.getIllegalScore() * illegalResult.getIllegalCount();
            }
        }
        List<ManualIntervention> manualInteventions = scenesResult.getManualInterventionList();
        if (manualInteventions != null) {
            scenesResult.setManualInterventionCount(manualInteventions.size());
            for (ManualIntervention manulIntevention : manualInteventions
                    ) {
                if (manulIntevention.getDeductScore() != null)
                    illegalScore += manulIntevention.getDeductScore();
            }
        }
        ScenesResult newscenesResult=new ScenesResult();
        newscenesResult.setScenesResultId(scenesResultId);
        if (scenesInfo.getScenesType() == Options.Road.getCode()) {
        	newscenesResult.setScenesResult(illegalScore);
        }else {
        	int scenesScore=scenesResult.getScenesScore();
            if (illegalScore>=scenesScore)
                newscenesResult.setScenesResult(0);
            else
                newscenesResult.setScenesResult(scenesScore-illegalScore);
        }
        
        int result=scenesResultMapper.updateByPrimaryKeySelective(newscenesResult);
  
        if (result==1&&(newscenesResult.getScenesResult()!=scenesResult.getScenesResult())){
        	int scoreChange=newscenesResult.getScenesResult()-scenesResult.getScenesResult();
            int scenesScoreChange = 0 ;
            int roadScoreChange = 0 ;
        	if (scenesInfo.getScenesType() == Options.Road.getCode()) {
        		if (scoreChange > 0) {
        			if (totalScoroRoad >= scenesInfo.getScenesScore()) {
        				scoreChange = 0;
        			} else  {
        				if ((totalScoroRoad + scoreChange) <  scenesInfo.getScenesScore() ){
        					scoreChange = 0 - scoreChange;
        				} else {
        					scoreChange = 0 -(scenesInfo.getScenesScore() - totalScoroRoad);
        				}
        			}
        		} else {
        			if (totalScoroRoad  >= scenesInfo.getScenesScore()) {
        				if (totalScoroRoad + scoreChange >= scenesInfo.getScenesScore()){
        					scoreChange = 0;
        				} else {
        					scoreChange =  scenesInfo.getScenesScore() - (totalScoroRoad + scoreChange);
        				}	
        			} else  {
        				scoreChange = -scoreChange;
        			}
        		}
        		roadScoreChange = scoreChange;
        	} else {
        		scenesScoreChange = scoreChange;
        	}
            int result1 = stadiumResultService.updateStadiumResult(scenesResult.getStadiumResultId(),scoreChange,scenesScoreChange,roadScoreChange);
            return result1;
        }
        return result;
    }

    @Override
    public int deleteScenesResult(int scenesResultId) {
        int result = scenesResultMapper.deleteScenesResult(scenesResultId);
        return result;
    }

    @Override
    public ScenesResult getScenesResultDetail(int scenesResultId){
        ScenesResult scenesResult = scenesResultMapper.getScenesResultByIdWithIllegalAndManu(scenesResultId);

        return scenesResult;
    }

	@Override
	public Map<String, Object> getStadiumTeamByScenesResult(int scenesResultId) {
		Map<String,Object> dataMap = scenesResultMapper.getStadiumScenesTeamByScenesResult(scenesResultId);
		return dataMap;
	}

	@Override
	public List<ScenesResult> listRoadScenesResult(int stadiumResultId) {
		List<ScenesResult> data = scenesResultMapper.listRoadResult(stadiumResultId);
		return data;
	}


}
